package com.zlz.blog.server.oauth.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.zlz.blog.manage.common.constants.CommonConstants;
import com.zlz.blog.manage.common.entity.oauth.LoginResult;
import com.zlz.blog.manage.common.entity.oauth.LoginUser;
import com.zlz.blog.manage.common.entity.oauth.SysRole;
import com.zlz.blog.manage.common.enums.LoginTypeEnum;
import com.zlz.blog.manage.common.exception.BlogException;
import com.zlz.blog.manage.common.response.ResultSet;
import com.zlz.blog.manage.common.template.EmailRedisTemplate;
import com.zlz.blog.manage.common.util.EncryptionUtil;
import com.zlz.blog.manage.common.util.SqlResultUtil;
import com.zlz.blog.server.oauth.mapper.AuthenticationMapper;
import com.zlz.blog.server.oauth.mapper.LoginUserMapper;
import com.zlz.blog.server.oauth.service.LoginUserService;
import com.zlz.blog.server.util.LoginUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author zhulinzhong
 * @version 1.0 CreateTime:2020-11-18 11:54
 * @description
 */
@Service
public class LoginUserServiceImpl implements LoginUserService {

    @Resource
    private LoginUserMapper userMapper;
    @Resource
    private AuthenticationMapper authenticationMapper;
    @Resource
    private LoginUtil loginUtil;
    @Resource
    private RedisTemplate<Object, EmailRedisTemplate> emailRedisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ResultSet<LoginResult> registerUser(HttpServletRequest request, LoginUser loginUser, String type) {
        Optional<LoginUser> loginUserOpt = Optional.of(loginUser);
        Optional<LoginTypeEnum> loginTypeEnumOptional = LoginTypeEnum.getLoginTypeEnumOptional(type);
        if (!loginTypeEnumOptional.isPresent()) {
            return ResultSet.error("注册失败！");
        }

        switch (loginTypeEnumOptional.get()) {
            case PASSWORD:
                String username = loginUserOpt.get().getUsername();
                QueryWrapper<LoginUser> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("username", username);
                int count = userMapper.selectCount(queryWrapper);
                if (count != 0) {
                    return ResultSet.error("用户名已经存在,请尝试新的用户名");
                }
                String salt = UUID.randomUUID().toString();
                String password = EncryptionUtil.md5Encrypt(loginUserOpt.get().getPassword(), salt);
                LoginUser user = new LoginUser();
                long id = IdWorker.getId();
                Date now = new Date();
                user.setId(id);
                user.setSalt(salt);
                user.setUsername(username);
                user.setPassword(password);
                user.setCreator(id);
                user.setLastModifier(id);
                user.setCreatedTime(now);
                user.setLastModifiedTime(now);
                int insert = userMapper.insert(user);
                if (insert == 1) {
                    return ResultSet.success(loginUtil.setSession(request, user));
                }
                return ResultSet.error("注册失败");
            case EMAIL_VERIFICATION_CODE:
                break;
            case PHONE_VERIFICATION_CODE:
                break;
            default:
                return ResultSet.error("注册失败");
        }
        return ResultSet.error("注册失败");
    }

    @Override
    public ResultSet<LoginResult> login(HttpServletRequest request, LoginUser loginUser, String type) {
        loginUser = Optional.of(loginUser).orElseThrow(() -> new BlogException("登录用户信息为空"));
        Optional<LoginTypeEnum> loginTypeEnumOptional = LoginTypeEnum.getLoginTypeEnumOptional(type);
        if (!loginTypeEnumOptional.isPresent()) {
            return ResultSet.loginError("登录失败，请检查数据！");
        }
        switch (loginTypeEnumOptional.get()) {
            case PASSWORD:
                String username = loginUser.getUsername();
                QueryWrapper<LoginUser> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("username", username);
                LoginUser dataUser = userMapper.selectOne(queryWrapper);
                if (dataUser == null) {
                    return ResultSet.loginError("用户名或密码错误！");
                }
                if (!dataUser.getPassword().equals(EncryptionUtil.md5Encrypt(loginUser.getPassword(), dataUser.getSalt()))) {
                    return ResultSet.loginError("用户名或密码错误！");
                }
                List<SysRole> roles = authenticationMapper.getAuthenticationInfo(dataUser.getId());
                dataUser.setSysRoles(roles);
                return ResultSet.success(loginUtil.setSession(request, dataUser));
            case EMAIL_VERIFICATION_CODE:
                break;
            case PHONE_VERIFICATION_CODE:
                break;
            default:
                return ResultSet.error("登录失败！");
        }
        return ResultSet.error("登录失败！");
    }

    @Override
    public LoginUser findByEmail(String email) {
        Optional<String> oName = Optional.of(email);

        // 查询用户
        QueryWrapper<LoginUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", oName.get())
                .select("id", "email", "phone", "username");
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public LoginUser findByUsername(String name) {
        Optional<String> oName = Optional.of(name);

        // 查询用户
        QueryWrapper<LoginUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", oName.get())
                .select("id", "email", "phone", "username", "salt", "password");
        LoginUser userData = userMapper.selectOne(queryWrapper);

        if (null != userData) {
            // 获权限信息
            List<SysRole> roles = authenticationMapper.getAuthenticationInfo(userData.getId());
            userData.setSysRoles(roles);
        }
        return userData;
    }

    @Override
    public LoginUser findByUserId(Long userId) {
        // 获权限信息
        List<SysRole> roles = authenticationMapper.getAuthenticationInfo(userId);
        LoginUser authenticationInfo = new LoginUser();
        authenticationInfo.setSysRoles(roles);
        return authenticationInfo;
    }
}
